00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef GENSLABMAP_HPP_
00018 #define GENSLABMAP_HPP_
00019
00020 #include <boost/smart_ptr/shared_ptr.hpp>
00021 #include <ga.h>
00022 #include "gridpack/parallel/parallel.hpp"
00023 #include <gridpack/parallel/distributed.hpp>
00024 #include <gridpack/component/base_component.hpp>
00025 #include <gridpack/network/base_network.hpp>
00026 #include <gridpack/utilities/exception.hpp>
00027 #include <gridpack/math/vector.hpp>
00028
00029
00030
00031 namespace gridpack {
00032 namespace mapper {
00033
00034 template <class _network>
00035 class GenSlabMap {
00036 public:
00037
00038
00039
00040
00041
00042
00043 GenSlabMap(boost::shared_ptr<_network> network)
00044 : p_network(network)
00045 {
00046 p_Offsets = NULL;
00047
00048 p_timer = NULL;
00049
00050
00051 p_GAgrp = network->communicator().getGroup();
00052 p_me = GA_Pgroup_nodeid(p_GAgrp);
00053 p_nNodes = GA_Pgroup_nnodes(p_GAgrp);
00054
00055 p_Offsets = new int[p_nNodes];
00056
00057 p_nBuses = p_network->numBuses();
00058 p_nBranches = p_network->numBranches();
00059
00060 getDimensions();
00061 setOffsets();
00062 setIndices();
00063 GA_Pgroup_sync(p_GAgrp);
00064 }
00065
00066 ~GenSlabMap()
00067 {
00068 if (p_Offsets != NULL) delete [] p_Offsets;
00069 GA_Pgroup_sync(p_GAgrp);
00070 }
00071
00072
00073
00074
00075
00076 boost::shared_ptr<gridpack::math::Matrix> mapToMatrix(void)
00077 {
00078 gridpack::parallel::Communicator comm = p_network->communicator();
00079 int blockSize = p_maxIndex-p_minIndex+1;
00080 #if 0
00081 boost::shared_ptr<gridpack::math::Matrix>
00082 Ret(new gridpack::math::Matrix(comm, blockSize,p_nColumns,
00083 gridpack::math::Dense));
00084 #else
00085 boost::shared_ptr<gridpack::math::Matrix>
00086 Ret(gridpack::math::Matrix::createDense(comm,
00087 0,p_nColumns,blockSize,0));
00088 #endif
00089 loadBusData(*Ret,false);
00090 loadBranchData(*Ret,false);
00091 GA_Pgroup_sync(p_GAgrp);
00092 Ret->ready();
00093 return Ret;
00094 }
00095
00096
00097
00098
00099
00100
00101 gridpack::math::Matrix* intMapToMatrix(void)
00102 {
00103 gridpack::parallel::Communicator comm = p_network->communicator();
00104 int blockSize = p_maxIndex-p_minIndex+1;
00105 #if 1
00106 gridpack::math::Matrix*
00107 Ret(new gridpack::math::Matrix(comm, blockSize,p_nColumns,
00108 gridpack::math::Dense));
00109 #else
00110 boost::shared_ptr<gridpack::math::Matrix>
00111 Ret(gridpack::math::Matrix::createDense(comm,
00112 0,p_nColumns,blockSize,0));
00113 #endif
00114
00115 loadBusData(*Ret,false);
00116 loadBranchData(*Ret,false);
00117 GA_Pgroup_sync(p_GAgrp);
00118 Ret->ready();
00119 return Ret;
00120 }
00121
00122
00123
00124
00125
00126
00127 void mapToMatrix(gridpack::math::Matrix &matrix)
00128 {
00129 int t_set, t_bus, t_branch;
00130 matrix.zero();
00131 loadBusData(matrix,false);
00132 loadBranchData(matrix,false);
00133 GA_Pgroup_sync(p_GAgrp);
00134 matrix.ready();
00135 }
00136
00137
00138
00139
00140
00141 void mapToMatrix(boost::shared_ptr<gridpack::math::Matrix> &matrix)
00142 {
00143 mapToMatrix(*matrix);
00144 }
00145
00146
00147
00148
00149
00150
00151 void mapToNetwork(const gridpack::math::Matrix &matrix)
00152 {
00153 #if 1
00154 int i, j, k;
00155 ComplexType *values;
00156 ComplexType **varray;
00157 ComplexType **vptr;
00158 int *idx;
00159 int *iptr;
00160 int ncols, nrows;
00161
00162 idx = new int[p_busRows];
00163 values = new ComplexType[p_nColumns*p_busRows];
00164 varray = new ComplexType*[p_busRows];
00165 for (i=0; i<p_busRows; i++) {
00166 varray[i] = values + i*p_nColumns;
00167 }
00168 iptr = idx;
00169 for (i=0; i<p_nBuses; i++) {
00170 if (p_network->getActiveBus(i)) {
00171 p_network->getBus(i)->slabSize(&nrows,&ncols);
00172 p_network->getBus(i)->slabGetRowIndices(iptr);
00173 iptr += nrows;
00174 }
00175 }
00176 matrix.getRowBlock(p_busRows, idx, values);
00177 vptr = varray;
00178 for (i=0; i<p_nBuses; i++) {
00179 if (p_network->getActiveBus(i)) {
00180 p_network->getBus(i)->slabSize(&nrows,&ncols);
00181 p_network->getBus(i)->slabSetValues(vptr);
00182 vptr += nrows;
00183 }
00184 }
00185 delete [] idx;
00186 delete [] varray;
00187 delete [] values;
00188
00189 idx = new int[p_branchRows];
00190 values = new ComplexType[p_nColumns*p_branchRows];
00191 varray = new ComplexType*[p_branchRows];
00192 for (i=0; i<p_branchRows; i++) {
00193 varray[i] = values + i*p_nColumns;
00194 }
00195 iptr = idx;
00196 for (i=0; i<p_nBranches; i++) {
00197 if (p_network->getActiveBranch(i)) {
00198 p_network->getBranch(i)->slabSize(&nrows,&ncols);
00199 p_network->getBranch(i)->slabGetRowIndices(iptr);
00200 iptr += nrows;
00201 }
00202 }
00203 matrix.getRowBlock(p_branchRows, idx, values);
00204 vptr = varray;
00205 for (i=0; i<p_nBranches; i++) {
00206 if (p_network->getActiveBranch(i)) {
00207 p_network->getBranch(i)->slabSize(&nrows,&ncols);
00208 p_network->getBranch(i)->slabSetValues(vptr);
00209 vptr += nrows;
00210 }
00211 }
00212 delete [] idx;
00213 delete [] varray;
00214 delete [] values;
00215 GA_Pgroup_sync(p_GAgrp);
00216 #else
00217 int i, j, k;
00218 ComplexType **values = new ComplexType*[p_maxValues];
00219 for (i=0; i<p_maxValues; i++) {
00220 values[i] = new ComplexType[p_nColumns];
00221 }
00222 int *idx = new int[p_maxValues];
00223 int ncols, nrows;
00224
00225 for (i=0; i<p_nBuses; i++) {
00226 if (p_network->getActiveBus(i)) {
00227 p_network->getBus(i)->slabSize(&nrows,&ncols);
00228 p_network->getBus(i)->slabGetRowIndices(idx);
00229 for (j=0; j<nrows; j++) {
00230 for (k=0; k<ncols; k++) {
00231 matrix.getElement(idx[j], k, (values[j])[k]);
00232 }
00233 }
00234 p_network->getBus(i)->slabSetValues(values);
00235 }
00236 }
00237
00238 for (i=0; i<p_nBranches; i++) {
00239 if (p_network->getActiveBranch(i)) {
00240 p_network->getBranch(i)->slabSize(&nrows,&ncols);
00241 p_network->getBranch(i)->slabGetRowIndices(idx);
00242 for (j=0; j<nrows; j++) {
00243 for (k=0; k<ncols; k++) {
00244 matrix.getElement(idx[j], k, (values[j])[k]);
00245 }
00246 }
00247 p_network->getBranch(i)->slabSetValues(values);
00248 }
00249 }
00250 for (i=0; i<p_maxValues; i++) {
00251 delete[] values[i];
00252 }
00253 delete [] values;
00254 delete [] idx;
00255 GA_Pgroup_sync(p_GAgrp);
00256 #endif
00257 }
00258
00259
00260
00261
00262
00263
00264 void mapToNetwork(boost::shared_ptr<gridpack::math::Matrix> &matrix)
00265 {
00266 mapToNetwork(*matrix);
00267 }
00268
00269 private:
00270
00271
00272
00273
00274
00275 bool isLocalBranch(int idx)
00276 {
00277 int jdx1, jdx2;
00278 p_network->getBranchEndpoints(idx, &jdx1, &jdx2);
00279 bool check = true;
00280 check = check && p_network->getActiveBus(jdx1);
00281 check = check && p_network->getActiveBus(jdx2);
00282 return check;
00283 }
00284
00285
00286
00287
00288
00289 void getDimensions(void)
00290 {
00291 int i, ival, jval;
00292
00293 int nRows = 0;
00294 int nCols = 0;
00295 bool okCols = true;
00296
00297 p_maxValues = 0;
00298 p_busRows = 0;
00299 for (i=0; i<p_nBuses; i++) {
00300 if (p_network->getActiveBus(i)) {
00301 p_network->getBus(i)->slabSize(&ival,&jval);
00302 if (p_maxValues < ival) p_maxValues = ival;
00303 nRows += ival;
00304 p_busRows += ival;
00305 if (nCols == 0 && ival > 0) nCols = jval;
00306 if (ival > 0 && jval != nCols) okCols = false;
00307 }
00308 }
00309
00310 p_branchRows = 0;
00311 for (i=0; i<p_nBranches; i++) {
00312 if (p_network->getActiveBranch(i)) {
00313 p_network->getBranch(i)->slabSize(&ival,&jval);
00314 if (p_maxValues < ival) p_maxValues = ival;
00315 nRows += ival;
00316 p_branchRows += ival;
00317 if (nCols == 0 && ival > 0) nCols = jval;
00318 if (ival > 0 && jval != nCols) okCols = false;
00319 }
00320 }
00321
00322 int *sizebuf = new int[p_nNodes];
00323 for (i=0; i<p_nNodes; i++) {
00324 sizebuf[i] = 0;
00325 }
00326 sizebuf[p_me] = nRows;
00327 char plus[2];
00328 strcpy(plus,"+");
00329 GA_Pgroup_igop(p_GAgrp, sizebuf, p_nNodes, plus);
00330 int maxCols, minCols;
00331 if (!okCols) {
00332 minCols = -1;
00333 } else {
00334 minCols = nCols;
00335 }
00336 char cmin[4];
00337 strcpy(cmin,"min");
00338 GA_Pgroup_igop(p_GAgrp, &minCols, 1, cmin);
00339 maxCols = nCols;
00340 char cmax[4];
00341 strcpy(cmax,"max");
00342 GA_Pgroup_igop(p_GAgrp, &maxCols, 1, cmax);
00343 if (maxCols != minCols) okCols = false;
00344 if (!okCols && p_me == 0) {
00345 char buf[512];
00346 sprintf(buf,"(GenSlabMap) Number of columns not uniform across all processors\n");
00347 throw gridpack::Exception(buf);
00348 }
00349
00350 p_Dim = sizebuf[0];
00351 p_nColumns = nCols;
00352 p_Offsets[0] = 0;
00353 for (i=1; i<p_nNodes; i++) {
00354 p_Dim += sizebuf[i];
00355 p_Offsets[i] = p_Offsets[i-1] + sizebuf[i-1];
00356 }
00357 p_minIndex = p_Offsets[p_me];
00358 if (p_me < p_nNodes-1) {
00359 p_maxIndex = p_Offsets[p_me+1] - 1;
00360 } else {
00361 p_maxIndex = p_Dim - 1;
00362 }
00363 delete [] sizebuf;
00364 }
00365
00366
00367
00368
00369 void setOffsets(void)
00370 {
00371
00372 int i,j,jdx,jdx1,jdx2,ival,jval;
00373 int *i_bus_offsets = new int[p_nBuses];
00374 int *i_branch_offsets = new int[p_nBranches];
00375 for (i=0; i<p_nBuses; i++) {
00376 i_bus_offsets[i] = 0;
00377 }
00378 for (i=0; i<p_nBranches; i++) {
00379 i_branch_offsets[i] = 0;
00380 }
00381 int icnt = 0;
00382 int nsize;
00383
00384 for (i=0; i<p_nBuses; i++) {
00385 if (p_network->getActiveBus(i)) {
00386 i_bus_offsets[i] = icnt;
00387 p_network->getBus(i)->slabSize(&ival,&jval);
00388 icnt += ival;
00389 std::vector<int> nghbrs = p_network->getConnectedBranches(i);
00390 nsize = nghbrs.size();
00391 for (j=0; j<nsize; j++) {
00392
00393
00394
00395
00396 jdx = nghbrs[j];
00397 if (isLocalBranch(jdx)) {
00398 p_network->getBranchEndpoints(jdx,&jdx1,&jdx2);
00399 if (jdx1 == i) {
00400 i_branch_offsets[jdx] = icnt;
00401 p_network->getBranch(jdx)->slabSize(&ival,&jval);
00402 icnt += ival;
00403 }
00404 } else {
00405 if (p_network->getActiveBranch(jdx)) {
00406 i_branch_offsets[jdx] = icnt;
00407 p_network->getBranch(jdx)->slabSize(&ival,&jval);
00408 icnt += ival;
00409 }
00410 }
00411 }
00412 }
00413 }
00414
00415
00416 int **i_bus_index = new int*[p_nBuses];
00417 int **i_branch_index = new int*[p_nBranches];
00418 int *i_bus_index_buf = new int[p_nBuses];
00419 int *i_branch_index_buf = new int[p_nBranches];
00420 int *i_bus_value_buf = new int[p_nBuses];
00421 int *i_branch_value_buf = new int[p_nBranches];
00422 int i_bus_cnt = 0;
00423 int i_branch_cnt = 0;
00424 int row_offset = p_Offsets[p_me];
00425 int nbus = 0;
00426 int nbranch = 0;
00427 for (i=0; i<p_nBuses; i++) {
00428 if (p_network->getActiveBus(i)) {
00429 nbus++;
00430 i_bus_value_buf[i_bus_cnt] = i_bus_offsets[i]+row_offset;
00431 i_bus_index_buf[i_bus_cnt] = p_network->getGlobalBusIndex(i);
00432 i_bus_index[i_bus_cnt] = &i_bus_index_buf[i_bus_cnt];
00433 i_bus_cnt++;
00434 }
00435 }
00436 for (i=0; i<p_nBranches; i++) {
00437 if (p_network->getActiveBranch(i)) {
00438 nbranch++;
00439 i_branch_value_buf[i_branch_cnt] = i_branch_offsets[i]+row_offset;
00440 i_branch_index_buf[i_branch_cnt] = p_network->getGlobalBranchIndex(i);
00441 i_branch_index[i_branch_cnt] = &i_branch_index_buf[i_branch_cnt];
00442 i_branch_cnt++;
00443 }
00444 }
00445 delete [] i_bus_offsets;
00446 delete [] i_branch_offsets;
00447
00448
00449 int *t_busMap = new int[p_nNodes];
00450 int *t_branchMap = new int[p_nNodes];
00451 for (i=0; i<p_nNodes; i++) {
00452 t_busMap[i] = 0;
00453 t_branchMap[i] = 0;
00454 }
00455 t_busMap[p_me] = nbus;
00456 t_branchMap[p_me] = nbranch;
00457 char plus[2];
00458 strcpy(plus,"+");
00459 GA_Pgroup_igop(p_GAgrp, t_busMap, p_nNodes, plus);
00460 GA_Pgroup_igop(p_GAgrp, t_branchMap, p_nNodes, plus);
00461 int *busMap = new int[p_nNodes];
00462 int *branchMap = new int[p_nNodes];
00463 busMap[0] = 0;
00464 branchMap[0] = 0;
00465 int total_buses = t_busMap[0];
00466 int total_branches = t_branchMap[0];
00467 for (i=1; i<p_nNodes; i++) {
00468 busMap[i] = busMap[i-1] + t_busMap[i-1];
00469 total_buses += t_busMap[i];
00470 branchMap[i] = branchMap[i-1] + t_branchMap[i-1];
00471 total_branches += t_branchMap[i];
00472 }
00473 delete [] t_busMap;
00474 delete [] t_branchMap;
00475
00476 int one = 1;
00477 g_bus_offsets = GA_Create_handle();
00478 GA_Set_data(g_bus_offsets, one, &total_buses, C_INT);
00479 GA_Set_irreg_distr(g_bus_offsets, busMap, &p_nNodes);
00480 GA_Set_pgroup(g_bus_offsets, p_GAgrp);
00481 if (!GA_Allocate(g_bus_offsets)) {
00482 char buf[256];
00483 sprintf(buf,"GenSlabMap::setOffsets: Unable to allocate distributed array for bus offsets\n");
00484 printf("%s",buf);
00485 throw gridpack::Exception(buf);
00486 }
00487 GA_Zero(g_bus_offsets);
00488
00489 g_branch_offsets = GA_Create_handle();
00490 GA_Set_data(g_branch_offsets, one, &total_branches, C_INT);
00491 GA_Set_irreg_distr(g_branch_offsets, branchMap, &p_nNodes);
00492 GA_Set_pgroup(g_branch_offsets, p_GAgrp);
00493 if (!GA_Allocate(g_branch_offsets)) {
00494 char buf[256];
00495 sprintf(buf,"GenSlabMap::setOffsets: Unable to allocate distributed array for branch offsets\n");
00496 printf("%s",buf);
00497 throw gridpack::Exception(buf);
00498 }
00499 GA_Zero(g_branch_offsets);
00500
00501 delete [] busMap;
00502 delete [] branchMap;
00503
00504
00505 NGA_Scatter(g_bus_offsets, i_bus_value_buf, i_bus_index, i_bus_cnt);
00506 NGA_Scatter(g_branch_offsets, i_branch_value_buf, i_branch_index, i_branch_cnt);
00507 NGA_Pgroup_sync(p_GAgrp);
00508
00509 delete [] i_bus_index;
00510 delete [] i_branch_index;
00511
00512 delete [] i_bus_index_buf;
00513 delete [] i_branch_index_buf;
00514 delete [] i_bus_value_buf;
00515 delete [] i_branch_value_buf;
00516 }
00517
00518
00519
00520
00521
00522
00523 void setIndices(void)
00524 {
00525
00526 int **bus_index = new int*[p_nBuses];
00527 int **branch_index = new int*[p_nBranches];
00528 int *bus_index_buf = new int[p_nBuses];
00529 int *branch_index_buf = new int[p_nBranches];
00530 int *i_bus_value_buf = new int[p_nBuses];
00531 int *i_branch_value_buf = new int[p_nBranches];
00532 int i, j;
00533
00534 for (i=0; i<p_nBuses; i++) {
00535 bus_index_buf[i] = p_network->getGlobalBusIndex(i);
00536 bus_index[i] = &bus_index_buf[i];
00537 }
00538 for (i=0; i<p_nBranches; i++) {
00539 branch_index_buf[i] = p_network->getGlobalBranchIndex(i);
00540 branch_index[i] = &branch_index_buf[i];
00541 }
00542 NGA_Gather(g_bus_offsets, i_bus_value_buf, bus_index, p_nBuses);
00543 NGA_Gather(g_branch_offsets, i_branch_value_buf, branch_index, p_nBranches);
00544
00545
00546 int offset, nrows, ncols, idx;
00547 for (i=0; i<p_nBuses; i++) {
00548 p_network->getBus(i)->slabSize(&nrows,&ncols);
00549 if (nrows > 0) {
00550 offset = i_bus_value_buf[i];
00551 for (j=0; j<nrows; j++) {
00552 idx = offset+j;
00553 p_network->getBus(i)->slabSetRowIndex(j,idx);
00554 }
00555 }
00556 }
00557 for (i=0; i<p_nBranches; i++) {
00558 p_network->getBranch(i)->slabSize(&nrows,&ncols);
00559 if (nrows > 0) {
00560 offset = i_branch_value_buf[i];
00561 for (j=0; j<nrows; j++) {
00562 idx = offset+j;
00563 p_network->getBranch(i)->slabSetRowIndex(j,idx);
00564 }
00565 }
00566 }
00567
00568 delete [] bus_index;
00569 delete [] branch_index;
00570
00571 delete [] bus_index_buf;
00572 delete [] branch_index_buf;
00573 delete [] i_bus_value_buf;
00574 delete [] i_branch_value_buf;
00575
00576
00577 GA_Destroy(g_bus_offsets);
00578 GA_Destroy(g_branch_offsets);
00579 }
00580
00581
00582
00583
00584
00585
00586 void loadBusData(gridpack::math::Matrix &matrix, bool flag)
00587 {
00588 int i, j, k, ivals, jvals;
00589 std::vector<ComplexType*> values;
00590 for (i=0; i<p_maxValues; i++) {
00591 values.push_back(new ComplexType[p_nColumns]);
00592 }
00593 int *idx = new int[p_maxValues];
00594 for (i=0; i<p_nBuses; i++) {
00595 if (p_network->getActiveBus(i)) {
00596 p_network->getBus(i)->slabSize(&ivals,&jvals);
00597 p_network->getBus(i)->slabGetValues(values, idx);
00598 for (j=0; j<ivals; j++) {
00599 if (flag) {
00600 for (k=0; k<p_nColumns; k++) {
00601 matrix.addElement(idx[j],k,(values[j])[k]);
00602 }
00603 } else {
00604 for (k=0; k<p_nColumns; k++) {
00605 matrix.setElement(idx[j],k,(values[j])[k]);
00606 }
00607 }
00608 }
00609 }
00610 }
00611 for (i=0; i<p_maxValues; i++) {
00612 delete [] values[i];
00613 }
00614 delete [] idx;
00615 }
00616
00617
00618
00619
00620
00621
00622 void loadBranchData(gridpack::math::Matrix &matrix, bool flag)
00623 {
00624 int i, j, k, ivals, jvals;
00625 std::vector<ComplexType*> values;
00626 for (i=0; i<p_maxValues; i++) {
00627 values.push_back(new ComplexType[p_nColumns]);
00628 }
00629 int *idx = new int[p_maxValues];
00630 for (i=0; i<p_nBranches; i++) {
00631 if (p_network->getActiveBranch(i)) {
00632 p_network->getBranch(i)->slabSize(&ivals,&jvals);
00633 p_network->getBranch(i)->slabGetValues(values,idx);
00634 for (j=0; j<ivals; j++) {
00635 if (idx[j] >= p_minIndex && idx[j] <= p_maxIndex) {
00636 if (flag) {
00637 for (k=0; k<p_nColumns; k++) {
00638 matrix.addElement(idx[j],k,(values[j])[k]);
00639 }
00640 } else {
00641 for (k=0; k<p_nColumns; k++) {
00642 matrix.setElement(idx[j],k,(values[j])[k]);
00643 }
00644 }
00645 }
00646 }
00647 }
00648 }
00649 for (i=0; i<p_maxValues; i++) {
00650 delete [] values[i];
00651 }
00652 delete [] idx;
00653 }
00654
00655
00656 int p_me;
00657 int p_nNodes;
00658
00659
00660 boost::shared_ptr<_network> p_network;
00661 int p_nBuses;
00662 int p_nBranches;
00663
00664
00665 int p_nColumns;
00666 int p_busRows;
00667 int p_branchRows;
00668 int p_Dim;
00669 int p_minIndex;
00670 int p_maxIndex;
00671 int p_maxValues;
00672 #ifdef NZ_PER_ROW
00673 int* p_nz_per_row;
00674 #endif
00675
00676 int* p_Offsets;
00677
00678
00679 int g_bus_offsets;
00680 int g_branch_offsets;
00681 int p_GAgrp;
00682
00683
00684 gridpack::utility::CoarseTimer *p_timer;
00685
00686 };
00687
00688 }
00689 }
00690
00691 #endif //GENSLABMAP_HPP_